# 浏览器工作原理, 向服务端发送一个请求,服务端验证你的请求,如果正确,给你的浏览器返回一个文件,
# 浏览器接收到文件,将文件里面的代码渲染成你看到的漂亮美丽的模样.

# 什么叫爬虫?
# 1. 利用代码模拟一个浏览器,进行浏览器的工作流程得到一堆源代码.
# 2. 对源代码进行数据清洗得到我想要数据.

# import requests
# ret = requests.get('http://www.baidu.com')
# if ret.status_code == 200:
#     print(ret.text)

"""
# 版本一:
# from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
# import time
# import random
# import os
# import requests
#
#
# def task(url):
#     '''模拟的就是爬取多个源代码 一定有IO操作'''
#     ret = requests.get(url)
#     if ret.status_code == 200:
#         return ret.text
#
# def parse(content):
#     '''模拟对数据进行分析 一般没有IO'''
#     return len(content)
#
#
# if __name__ == '__main__':
#     '''串行 耗费时间长,不可取
#     ret = task('http://www.baidu.com')
#     print(parse(ret))
#
#     ret = task('http://www.JD.com')
#     print(parse(ret))
#
#     ret = task('http://www.taobao.com')
#     print(parse(ret))
#
#     ret = task('https://www.cnblogs.com/jin-xin/articles/7459977.html')
#     print(parse(ret))
#
#     '''
#     # 开启线程池,并发并行的执行
#     url_list = [
#         'http://www.baidu.com',
#         'http://www.JD.com',
#         'http://www.JD.com',
#         'http://www.JD.com',
#         'http://www.taobao.com',
#         'https://www.cnblogs.com/jin-xin/articles/7459977.html',
#         'https://www.luffycity.com/',
#         'https://www.cnblogs.com/jin-xin/articles/9811379.html',
#         'https://www.cnblogs.com/jin-xin/articles/11245654.html',
#         'https://www.sina.com.cn/',
#
#     ]
#     pool = ThreadPoolExecutor(4)
#     obj_list = []
#     for url in url_list:
#         obj = pool.submit(task,url)
#         obj_list.append(obj)
#
#     pool.shutdown(wait=True)
#     for res in obj_list:
#         print(parse(res.result()))
# # '''
# parse(res.result())
# parse(res.result())
# parse(res.result())
# parse(res.result())
# parse(res.result())
# parse(res.result())
# parse(res.result())
# parse(res.result())
# parse(res.result())
'''
# print('===主')
'''
# 版本一:
#     1. 异步发出10个任务,并发的执行,但是统一的接收所有的任务的返回值.(效率低,不能实时的获取结果)
#     2. 分析结果流程是串行,影响效率.
#          for res in obj_list:
#             print(parse(res.result()))
'''

# 版本二: 针对版本一的缺点2,改进,让串行编程并发或者并行.
# from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
# import time
# import random
# import os
# import requests
#
#
# def task(url):
#     '''模拟的就是爬取多个源代码 一定有IO操作'''
#     ret = requests.get(url)
#     if ret.status_code == 200:
#         return parse(ret.text)
#
#
# def parse(content):
#     '''模拟对数据进行分析 一般没有IO'''
#     return len(content)
#
#
# if __name__ == '__main__':
#
#     # 开启线程池,并发并行的执行
#     url_list = [
#         'http://www.baidu.com',
#         'http://www.JD.com',
#         'http://www.JD.com',
#         'http://www.JD.com',
#         'http://www.taobao.com',
#         'https://www.cnblogs.com/jin-xin/articles/7459977.html',
#         'https://www.luffycity.com/',
#         'https://www.cnblogs.com/jin-xin/articles/9811379.html',
#         'https://www.cnblogs.com/jin-xin/articles/11245654.html',
#         'https://www.sina.com.cn/',
#
#     ]
#     pool = ThreadPoolExecutor(4)
#     obj_list = []
#     for url in url_list:
#         obj = pool.submit(task, url)
#         obj_list.append(obj)
#     '''
#     # 1 在开一个线程进程池,并发并行的处理. 再开一个线程进程池,开销大.
#     # 2 将原来的任务扩大,
#     版本一:
#         线程池设置4个线程, 异步发起10个任务,每个任务是通过网页获取源码, 并发执行,
#         最后统一用列表回收10个任务, 串行着分析源码.
#     版本二:
#         线程池设置4个线程, 异步发起10个任务,每个任务是通过网页获取源码+数据分析, 并发执行,
#         最后将所有的结果展示出来.
#         耦合性增强了.
#         并发执行任务,此任务最好是IO阻塞,才能发挥最大的效果
#     '''
#     pool.shutdown(wait=True)
#     for res in obj_list:  # [obj1, obj2,obj3....obj10]
#         print(res.result())
#
"""
# 版本三:
# 基于 异步调用回收所有任务的结果我要做到实时回收结果,
# 并发执行任务每个任务只是处理IO阻塞的,不能增加新得功能.
# 异步调用 + 回调函数
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
import time
import random
import os
import requests


def task(url):
    '''模拟的就是爬取多个源代码 一定有IO操作'''
    ret = requests.get(url)
    if ret.status_code == 200:
        return ret.text


def parse(obj):
    '''模拟对数据进行分析 一般没有IO'''
    print(len(obj.result()))


if __name__ == '__main__':

    # 开启线程池,并发并行的执行
    url_list = [
        'http://www.baidu.com',
        'http://www.JD.com',
        'http://www.JD.com',
        'http://www.JD.com',
        'http://www.taobao.com',
        'https://www.cnblogs.com/jin-xin/articles/7459977.html',
        'https://www.luffycity.com/',
        'https://www.cnblogs.com/jin-xin/articles/9811379.html',
        'https://www.cnblogs.com/jin-xin/articles/11245654.html',
        'https://www.sina.com.cn/',

    ]
    pool = ThreadPoolExecutor(4)

    for url in url_list:
        obj = pool.submit(task, url)
        obj.add_done_callback(parse)

    '''
    线程池设置4个线程, 异步发起10个任务,每个任务是通过网页获取源码, 并发执行,
    当一个任务完成之后,将parse这个分析代码的任务交由剩余的空闲的线程去执行,你这个线程继续去处理其他任务.
    如果进程池+回调: 回调函数由主进程去执行.
    如果线程池+回调: 回到函数由空闲的线程去执行.
    '''

# 异步 回调是一回事儿?
# 异步站在发布任务的角度,
# 站在接收结果的角度: 回调函数 按顺序接收每个任务的结果,进行下一步处理.

# 异步 + 回调:
# 异步处理的IO类型.
# 回调处理非IO





















